package com.ipan.poi.utils;

import java.lang.reflect.Method;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;

/**
 * 属性工具类
 * 
 * @author iPan
 * @version 2013-9-28
 */
public class PoiBeanHelper extends PropertyUtils {

	/**
	 * 获取字段类型（支持获取父类属性）
	 */
	public static Class<?> getBeanType(Object bean, String fieldName) {
		Class<?> type = null;
		for (Class<?> superClass = bean.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
			try {
//				Method method = MethodUtils.getAccessibleMethod(bean.getClass(), "get" + StringUtils.capitalize(fieldName), new Class[0]);
//				if (method != null) {
//					type = method.getReturnType();
//					return type;
//				}
				// TODO:PropertyUtils无法获取父类的属性，在调用getPropertyType方法时候默认直接返回了Object对象，这是不对的。
				Method method = superClass.getDeclaredMethod("get" + StringUtils.capitalize(fieldName), null);
				if (method != null) {
					type = method.getReturnType();
					break;
				}
			} catch (Exception e) {
				// throw new IllegalArgumentException("实体[" + bean.getClass().getName() + "]中获取[" + fieldName + "]类型出错！");
			}
			try {
				Method method = superClass.getDeclaredMethod("is" + StringUtils.capitalize(fieldName), null);
				if (method != null) {
					type = method.getReturnType();
					break;
				}
			} catch (Exception e) {
			}
		}
		return type;
	}
	
	/**
	 * 获取字段值
	 */
	public static Object getBeanValue(Object bean, String fieldName) {
		Object value = null;
		try {
			value = PropertyUtils.getProperty(bean, fieldName);
		} catch (Exception e) {
			throw new IllegalArgumentException("实体[" + bean.getClass().getName() + "]中获取[" + fieldName + "]出错！");
		}
		return value;
	}
	
	/**
	 * 设置字段值（非严格的），有默认值；带有默认类型转换；
	 */
	public static void setBeanValue(Object bean, String fieldName, Object value) {
		try {
			BeanUtils.setProperty(bean, fieldName, value);
		} catch (Exception e) {
			throw new IllegalArgumentException("为实体[" + bean.getClass().getName() + "]的[" + fieldName + "]设值出错！");
		}
	}
	
	/**
	 * 设置字段值（严格的），没有默认值；无类型转换；
	 */
	public static void setBeanValueOfStrict(Object bean, String fieldName, Object value) {
		try {
			PropertyUtils.setProperty(bean, fieldName, value);
		} catch (Exception e) {
			throw new IllegalArgumentException("为实体[" + bean.getClass().getName() + "]的[" + fieldName + "]设值出错！");
		}
	}
	
	/**
	 * 设置字段值（严格的）并且带有自动类型转换；
	 */
	public static void setBeanValueOfAuto(Object bean, String fieldName, Object value) {
		Class<?> type = getBeanType(bean, fieldName);
		if (value == null) {
			setBeanValueOfStrict(bean, fieldName, null);
		} else {
			if (type.equals(value.getClass()) || type.isAssignableFrom(value.getClass())) {
				setBeanValueOfStrict(bean, fieldName, value);
			} else {
				Object cntVal = convertOfStrict(value, type);
				setBeanValueOfStrict(bean, fieldName, cntVal);
			}
		}
	}
	
	/**
	 * 类型转换，Object型转目标型；
	 */
	public static Object convertOfStrict(Object value, Class<?> targetType) {
		if (value == null) {
			return null;
		}
		Object result = null;
		result = PoiStrictConvertUtils.convert(value, targetType);
		return result;
	}
	
	/**
	 * 类型转换，String型转目标型；
	 */
	public static Object convertOfStrict(String value, Class<?> targetType) {
		if (value == null) {
			return null;
		}
		Object result = null;
		result = PoiStrictConvertUtils.convert(value, targetType);
		return result;
	}
	
}
